package com.pointwest.pls.console;

import java.io.File;
import java.io.FileWriter;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.HashMap;

import com.pointwest.pls.constant.Constant;
import com.pointwest.pls.core.SeatProcessor;
import com.pointwest.pls.displayDomain.EmployeeSeat;
import com.pointwest.pls.domain.*;

public class Core {

	/**
	 * Gets the employee location information
	 * @param employeeId
	 * @return
	 */
	public String searchEmployeeSeat(int employeeId) {
		SeatProcessor seatProc = new SeatProcessor();
		
		Seat seat = new Seat();
		EmployeeSeat empSeat = new EmployeeSeat();
		ArrayList<QuadrantSeat> quadrantSeats = new ArrayList<QuadrantSeat>();
		StringBuffer outputSearchTextFile = new StringBuffer();
		
		try {
			seat = seatProc.getSeat(employeeId);
			
			quadrantSeats = seatProc.getQuadrantMap(seat.getQuadrant());
			
			empSeat = setEmployeeSeat(seat);
			
			String employeeSeatInfo = displayEmplpoyeeInfo(empSeat);
			String quadrantMapInfo = displayQuadrantMap(quadrantSeats, employeeId);
			
			outputSearchTextFile.append(employeeSeatInfo);
			outputSearchTextFile.append("\r\n\r\n");
			outputSearchTextFile.append(quadrantMapInfo);
			
			
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
				
		return outputSearchTextFile.toString();
	}
	
	/**
	 * Exports to text file the seat information of an employee
	 * @param infoTextFile
	 * @param employeeId
	 */
	public void exportEmployeeSeatInfoToTextFile(String infoTextFile, int employeeId) {

		try {
			File file = new File(Constant.OUTPUT_TEXT_FILE_LOCATION + String.valueOf(employeeId) + ".txt");
			FileWriter fw = new FileWriter(file);

			fw.write(infoTextFile);

			fw.close();

		} catch (Exception e) {
			System.out.println(e);
		} finally {

		}

	}
	
	/**
	 * Updates the seat location of an employee
	 * @param newSeatCode
	 * @param employeeId
	 */
	public int updateEmployeeSeat(String newSeatCode, int employeeId) throws ClassNotFoundException, SQLException, Exception {
		SeatProcessor seatProcessor = new SeatProcessor();
		int rowsChanged = 0;
		rowsChanged = seatProcessor.updateSeat(employeeId, newSeatCode);
		return rowsChanged;
	}
	
	public int insertEmployeeSeat(String newSeatCode, int employeeId) throws ClassNotFoundException, SQLException, Exception {
		SeatProcessor seatProcessor = new SeatProcessor();
		int rowsChanged = 0;
		rowsChanged = seatProcessor.insertSeat(employeeId, newSeatCode);
		return rowsChanged;
	}
	
	public boolean checkSeatAvailability(String seatCode) throws SQLException, Exception{
		SeatProcessor seatProcessor = new SeatProcessor();
		boolean isAvail = seatProcessor.checkSeat(seatCode);
		return isAvail;
	}
	
	/**
	 * Removes the employee in a certain seat location
	 * @param seatCode
	 * @param employeeId
	 */
	public int removeSeatAssignment(String seatCode, int employeeId) throws ClassNotFoundException, SQLException, Exception {
		SeatProcessor seatProcessor = new SeatProcessor();
		int rowsChanged = 0;
		rowsChanged = seatProcessor.deleteSeat(employeeId, seatCode);
		return rowsChanged;
	}
	
	/**
	 * Sets the employee seat info
	 * @param seat
	 * @return
	 */
	private EmployeeSeat setEmployeeSeat(Seat seat) {
		EmployeeSeat empSeat = new EmployeeSeat();
		ArrayList<String> projectList = new ArrayList<String>();
	
		empSeat.setFullName(seat.getEmployee().getFullName());
		for (Project project : seat.getEmployee().getProjectList()) {
			projectList.add(project.getDescription());
		}
		empSeat.setProjectNameList(projectList);
		empSeat.setSeatCode(seat.getSeatCode());
		empSeat.setSeatType(seat.getSeatType().getDescription());
		empSeat.setQuadrant(seat.getQuadrant());
		empSeat.setLocalNumber(String.valueOf(seat.getLocalNumber()));

		return empSeat;
	}

	/**
	 * Displays in console the employee seat info
	 * @param employeeSeat
	 * @return
	 */
	private String displayEmplpoyeeInfo(EmployeeSeat employeeSeat) {
		String employeeSeatInfo = prepareEmployeeSeatInfoOutputString(employeeSeat);
		
		System.out.println(employeeSeatInfo);
		
		return employeeSeatInfo;
	}
	
	/**
	 * Displays the quadrant in which the employee belongs to
	 * @param quadrantSeats
	 * @param employeeId
	 * @return
	 */
	private String displayQuadrantMap(ArrayList<QuadrantSeat> quadrantSeats, int employeeId) {
		String quadrantMap = prepareQuadrantMapInfoOutputString(quadrantSeats, employeeId);
		
		System.out.println(quadrantMap);
		
		return quadrantMap;
	}
	
	/**
	 * Prepares the string output for the employee seat info
	 * @param employeeSeat
	 * @return
	 */
	private String prepareEmployeeSeatInfoOutputString (EmployeeSeat employeeSeat) {
		StringBuffer output = new StringBuffer();
		
		output.append("\r\nName: " + employeeSeat.getFullName());

		output.append("\r\nProject Name(s): ");
		for (int i = 0; i < employeeSeat.getProjectNameList().size(); i++) {
			output.append(employeeSeat.getProjectNameList().get(i));
			
			if (i < employeeSeat.getProjectNameList().size() - 1) {
				output.append(", ");
			}
		}

		
		output.append("\r\nSeat Number: " + employeeSeat.getSeatCode());
		output.append("\r\nSeat Type: " + employeeSeat.getSeatType());
		output.append("\r\nQuadrant Number: " + employeeSeat.getQuadrant());
		
		return output.toString();
	}
	
	/**
	 * Prepares the string output for the quadrant info
	 * @param quadrantSeats
	 * @param employeeId
	 * @return
	 */
	private String prepareQuadrantMapInfoOutputString (ArrayList<QuadrantSeat> quadrantSeats, int employeeId) {
		StringBuffer output = new StringBuffer();
		String[][] seatCodeArray = new String[Constant.QUADRANT_ROW_SIZE][Constant.QUADRANT_COLUMN_SIZE];
		String[][] employeeArray = new String[Constant.QUADRANT_ROW_SIZE][Constant.QUADRANT_COLUMN_SIZE];
		String[][] localNumberArray = new String[Constant.QUADRANT_ROW_SIZE][Constant.QUADRANT_COLUMN_SIZE];
		String[][] seatTypeArray = new String[Constant.QUADRANT_ROW_SIZE][Constant.QUADRANT_COLUMN_SIZE];

		employeeArray= prepareEmployeeArray(quadrantSeats);
		seatCodeArray = prepareSeatCodeArray(quadrantSeats);
		localNumberArray = prepareLocalNumberArray(quadrantSeats);
		seatTypeArray = prepareSeatTypeArray(quadrantSeats);
		
		for (int row = 0; row < Constant.QUADRANT_ROW_SIZE; row++) {
			//Seat Code
			for (int col = 0; col < Constant.QUADRANT_COLUMN_SIZE; col++) {
				output.append(seatCodeArray[row][col]);
				
				if (col < Constant.QUADRANT_COLUMN_SIZE - 1) {
					output.append("\t\t");
				}
			}
			
			output.append("\r\n");
			
			//Employee
			for (int col = 0; col < Constant.QUADRANT_COLUMN_SIZE; col++) {
				
				if (employeeArray[row][col] != null) {
					if (employeeArray[row][col].equals(String.valueOf(employeeId))) {
						output.append("**");
					}
					
					output.append(employeeArray[row][col]);
					
					if (employeeArray[row][col].equals(String.valueOf(employeeId))) {
						output.append("**");
					}
				} else {
					//Seat Type
					output.append(seatTypeArray[row][col]);
				}
				
				if (col < Constant.QUADRANT_COLUMN_SIZE - 1) {
					output.append("\t\t");
				}
			}
			
			output.append("\r\n");
			
			//Local Number
			for (int col = 0; col < Constant.QUADRANT_COLUMN_SIZE; col++) {
				if (localNumberArray[row][col] != null) {
					output.append("Loc. ");
					output.append(localNumberArray[row][col]);
				} else {
					output.append("\t");
				}
				
				if (col < Constant.QUADRANT_COLUMN_SIZE - 1) {
					output.append("\t\t");
				}
				
			}
			
			output.append("\r\n\r\n");
		}
		
		return output.toString();
	}
	
	/**
	 * Prepares an array of seat codes
	 * @param quadrantSeats
	 * @return
	 */
	private String[][] prepareSeatCodeArray(ArrayList<QuadrantSeat> quadrantSeats) {
		String[][] quadrantSeatCodeArray = new String[Constant.QUADRANT_ROW_SIZE][Constant.QUADRANT_COLUMN_SIZE];

		//Prepare Quadrant Seat Codes
		for (QuadrantSeat quadrantSeat : quadrantSeats) {
			quadrantSeatCodeArray[quadrantSeat.getRow()-1][quadrantSeat.getColumn()-1] = quadrantSeat.getSeatCode();
		}
		
		return quadrantSeatCodeArray;
	}
	
	/**
	 * Prepares an array of employee ids
	 * @param quadrantSeats
	 * @return
	 */
	private String[][] prepareEmployeeArray(ArrayList<QuadrantSeat> quadrantSeats) {
		String[][] quadrantEmployeeArray = new String[Constant.QUADRANT_ROW_SIZE][Constant.QUADRANT_COLUMN_SIZE];
		String existingEmployee;
		
		//Assign Employee
		for (QuadrantSeat quadrantSeat : quadrantSeats) {
			
			if (quadrantEmployeeArray[quadrantSeat.getRow()-1][quadrantSeat.getColumn()-1] == null){
				if (quadrantSeat.getEmployeeId() != null) {
				quadrantEmployeeArray[quadrantSeat.getRow()-1][quadrantSeat.getColumn()-1] = quadrantSeat.getEmployeeId();
				}
			} else {
				existingEmployee = quadrantEmployeeArray[quadrantSeat.getRow()-1][quadrantSeat.getColumn()];
				if (quadrantSeat.getEmployeeId() != null) {
					quadrantEmployeeArray[quadrantSeat.getRow()-1][quadrantSeat.getColumn()-1] = existingEmployee + ":" + quadrantSeat.getEmployeeId();
				}
			}
		}
		
		return quadrantEmployeeArray;
	}
	
	/**
	 * Prepares an array of local number
	 * @param quadrantSeats
	 * @return
	 */
	private String[][] prepareLocalNumberArray(ArrayList<QuadrantSeat> quadrantSeats) {
		String[][] localNumberArray = new String[Constant.QUADRANT_ROW_SIZE][Constant.QUADRANT_COLUMN_SIZE];
		
		for (QuadrantSeat quadrantSeat : quadrantSeats) {
			if (quadrantSeat.getLocalNumber() != 0) {

				localNumberArray[quadrantSeat.getRow()-1][quadrantSeat.getColumn()-1] = String.valueOf(quadrantSeat.getLocalNumber());
			}
		}
		
		return localNumberArray;
	}
	
	/**
	 * Prepares an array of seat type
	 * @param quadrantSeats
	 * @return
	 */
	private String[][] prepareSeatTypeArray(ArrayList<QuadrantSeat> quadrantSeats) {
		String[][] quadrantSeatTypeArray = new String[Constant.QUADRANT_ROW_SIZE][Constant.QUADRANT_COLUMN_SIZE];

		//Prepare Quadrant Seat Codes
		for (QuadrantSeat quadrantSeat : quadrantSeats) {
			quadrantSeatTypeArray[quadrantSeat.getRow()-1][quadrantSeat.getColumn()-1] = quadrantSeat.getSeatType();
		}
		
		return quadrantSeatTypeArray;
	}
	



}
